<template>
  <div class="page-container">
    <el-row style="text-align: center">
      <el-col :span="2" style="margin: 0 25px" v-for="item in stageList" :key="item.id" @click="stageChange(item.id)">
        <el-card :body-style="{padding: `0`}" shadow="never">
          <el-row justify="space-between">
            <div :class="['stateCell', item.id == params.stageId ? 'state-active' : '']">
              <h3 class="state-name">{{ item.label }}</h3>
              <h3 class="state-num">{{ item.num }}</h3>
            </div>
          </el-row>
        </el-card>
      </el-col>
    </el-row>

    <el-row style="margin-top: 10px">
      <el-button size="small" type="primary" :icon="Plus" @click="openAdd">新建</el-button>
      <el-input v-model="params.name" placeholder="请输入项目简称" size="small" clearable @keydown.enter.native="getProjectData" style="width: 180px;margin: 0 15px">
        <template #suffix>
          <el-icon :size="15" color="var(--el-color-primary)" @click="getProjectData">
            <ele-Search/>
          </el-icon>
        </template>
      </el-input>
    </el-row>

    <!-- 表格 -->
    <div class="table-box">
      <el-table :data="projectList" size="small" class="tableList" stripe>
        <el-table-column prop="nickname" label="项目简称" width="130" fixed="left">
          <template v-slot="scope">
            <span class="primary" @click="openDetail(scope.row)">{{ scope.row.nickname }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="description" label="项目描述" min-width="240" show-overflow-tooltip/>
        <el-table-column prop="stageName" label="项目阶段" width="130"/>
        <el-table-column prop="progress" label="进行比例" width="130">
          <template v-slot="{ row }">{{ row.progress }}%</template>
        </el-table-column>
        <el-table-column prop="createTime" label="创建时间" width="140"/>
        <el-table-column prop="budget" label="项目预算" width="130"/>
        <el-table-column prop="sumExpend" label="累计支出" width="130"/>
        <el-table-column prop="managerName" label="项目经理" width="130"/>
        <el-table-column prop="memberNames" label="项目成员" min-width="260">
          <template #header>
            <span style="margin-right: 2px">项目成员</span>
            <!-- 可筛选表头 -->
            <el-popover placement="bottom" :width="60" trigger="click" @after-leave="getProjectData">
              <template #reference>
                <el-icon :size="15" color="var(--el-color-primary)"><ele-Filter /></el-icon>
              </template>
              <el-scrollbar max-height="600px">
                <el-checkbox-group v-if="enterpriseUsers && enterpriseUsers.length > 0" v-model="filterIds">
                  <el-checkbox v-for="item in enterpriseUsers" :key="item.userId" :label="item.userId">{{ item.nickname }}</el-checkbox>
                </el-checkbox-group>
                <el-empty style="padding: 0;font-size: 12px" v-else :image-size="50" description="无数据" />
              </el-scrollbar>
            </el-popover>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <!-- 分页 -->
    <div class="page-block">
      <el-pagination
          v-model:current-page="params.current"
          v-model:page-size="params.size"
          :page-sizes="[10, 20, 30, 40]"
          :small="true"
          :disabled="false"
          :background="false"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          :hide-on-single-page="true"
          @size-change="sizeChange"
          @current-change="getProjectData"
      />
    </div>

    <el-dialog v-model="addVisible" title="新建项目" width="900px" top="7vh">
      <el-form :model="formData" :rules="formRules" label-width="110px" size="small" ref="formRef">
        <el-form-item label="项目简称" prop="nickname">
          <el-input v-model="formData.nickname" maxlength="4" clearable placeholder="请填写项目简称"/>
        </el-form-item>
        <el-form-item label="项目名称" prop="name">
          <el-input v-model="formData.name" maxlength="64" clearable placeholder="请填写项目名称"/>
        </el-form-item>
        <el-form-item label="项目描述" prop="description">
          <el-input v-model="formData.description" type="textarea" :rows="3" placeholder="请填写描述"/>
        </el-form-item>
        <el-form-item label="项目阶段" prop="stageId">
          <el-radio-group v-model="formData.stageId">
            <el-radio v-for="stage in stageList" :key="stage.id" :label="stage.id">{{ stage.label }}</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-row class="form-row">
          <el-col :span="12">
            <el-form-item label="项目归属" prop="deptId">
              <el-select v-model="formData.deptId" placeholder="请选择项目归属">
                <el-option v-for="item in deptList" :key="item.id" :value="item.id" :label="item.name"/>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="预计结束日期" prop="predictEndDate">
              <el-date-picker v-model="formData.predictEndDate" type="date" placeholder="请选择预计结束日期" value-format="YYYY-MM-DD" size="small" clearable/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row class="form-row">
          <el-col :span="12">
            <el-form-item label="项目经理" prop="managerId">
              <el-select v-model="formData.managerId" placeholder="请选择项目经理" clearable filterable>
                <el-option v-for="item in enterpriseUsers" :key="item.userId" :label="item.nickname" :value="item.userId"/>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="项目管理人" prop="managerList">
              <el-select v-model="formData.members" placeholder="请选择项目管理人" multiple filterable clearable value-key="userId">
                <el-option v-for="item in enterpriseUsers" :key="item.userId" :label="item.nickname" :value="item"/>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="项目组" prop="groups">
          <el-row style="width: 100%">
            <el-scrollbar max-height="240px">
              <el-tree :data="formData.groups" node-key="id" style="width: 100%" :props="groupTreeProps" default-expand-all>
                <template #default="{ node, data }">
                  <el-row style="width: 100%">
                    <el-col :span="8">
                      {{ data.name }}
                      <el-tag effect="plain" size="small" v-if="data.type == 1" class="leader">组长</el-tag>
                    </el-col>
                    <el-col :span="16" v-if="node.level == 1" class="options-btn">
                      <el-button type="primary" size="small" style="padding: 0;margin-right: 5px" text @click.stop="openAddMember(data)">添加</el-button>
                      <el-button type="danger" size="small" style="padding: 0" text @click.stop="removeGroup(data)">删除</el-button>
                    </el-col>
                    <el-col :span="16" v-else class="options-btn">
                      <el-button type="primary" size="small" v-if="data.type == 0" style="padding: 0;margin-right: 5px" text @click.stop="toLeader(data)">设为组长</el-button>
                      <el-button type="warning" size="small" v-else style="padding: 0;margin-right: 5px" text @click.stop="removeLeader(data)">取消组长</el-button>
                      <el-button type="danger" size="small" style="padding: 0" text @click.stop="removeMember(node, data)">移除</el-button>
                    </el-col>
                  </el-row>
                </template>
              </el-tree>
            </el-scrollbar>
            <el-button style="margin-top: 10px" type="primary" size="small" @click="addGroup">添加分组</el-button>
          </el-row>
        </el-form-item>
        <el-divider content-position="left">项目相关方</el-divider>
        <el-row v-for="(item, idx) in formData.relevantList" :key="idx" style="margin-bottom: 10px">
          <el-col :span="7" :offset="1">
            <el-input v-model="item.name" placeholder="请填写相关方名称" maxlength="128" clearable/>
          </el-col>
          <el-col :span="5" :offset="1">
            <el-input v-model="item.contactName" placeholder="请填写联系人" maxlength="32" clearable/>
          </el-col>
          <el-col :span="5" :offset="1">
            <el-input v-model="item.contactPhone" placeholder="请填写联系方式" maxlength="16" clearable/>
          </el-col>
          <el-col :span="2" :offset="1" class="relevant-icon">
            <el-button type="danger" text :icon="Minus" @click="minusRelevantItem(idx)" style="padding: 3px 5px"/>
          </el-col>
        </el-row>
        <el-row style="margin-top: 10px" class="relevant-icon">
          <el-col :offset="1">
            <el-button type="primary" text :icon="Plus" @click="addRelevantItem" style="padding: 3px 5px"/>
          </el-col>
        </el-row>
        <el-divider content-position="left">成本管理</el-divider>
        <el-form-item label="项目预算" prop="budget">
          <el-input-number v-model="formData.budget" :min="0" :max="999999999" :precision="2" :controls="false" style="width: 180px"/>
        </el-form-item>
        <el-form-item label="上传附件" prop="files">
          <Document style="margin-left: 30px;" :relevance-id="formData.id" :relevance-name="formData.nickname" code="Project" v-model:resultList="fileList" :limit="9"/>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button size="small" @click="addVisible = false">关闭</el-button>
          <el-button size="small" type="primary" @click="saveProject(formRef)">保存</el-button>
        </span>
      </template>
    </el-dialog>

    <el-dialog title="添加分组" width="450px" v-model="addGroupVisible">
      <el-form :model="groupData" :rules="groupRules" size="small" label-width="70px" ref="groupRef">
        <el-form-item label="名称" prop="name">
          <el-input v-model="groupData.name" placeholder="请填写分组名称" maxlength="64" @keydown.enter.native="saveGroup(groupRef)"/>
        </el-form-item>
        <el-form-item label="排序" prop="sort">
          <el-input-number v-model="groupData.sort" :min="0" :max="99999" :controls="false"/>
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="groupData.remark" placeholder="请填写备注" type="textarea" :rows="3"/>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button size="small" @click="addGroupVisible = false">关闭</el-button>
          <el-button size="small" type="primary" @click="saveGroup(groupRef)">保存</el-button>
        </span>
      </template>
    </el-dialog>

    <el-dialog v-model="addMemberShow" width="650px" title="添加组员">
      <el-transfer v-model="memberIds" :data="enterpriseUsers" :props="memberTreeProps" :titles="['企业人员列表', '组员列表']"/>
      <template #footer>
        <span class="dialog-footer">
          <el-button size="small" @click="addMemberShow = false">关闭</el-button>
          <el-button size="small" type="primary" @click="saveMembers">保存</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 项目详情  -->
    <project-detail v-model:drawer="drawer" v-model:projectData="detailData" v-model:deptList="deptList" v-model:enterpriseUsers="enterpriseUsers"/>
  </div>
</template>

<script>
import {onMounted, reactive, toRefs, ref} from 'vue'
import {getProjectPage, createProject} from '/@/api/project'
import {getStageList} from '/@/api/project/stage'
import ProjectDetail from '/@/views/project/components/detail.vue'
import {Plus, Minus} from '@element-plus/icons-vue'
import {getEnterpriseUsers} from '/@/api/sys/user'
import {ElMessage} from 'element-plus'
import Document from '/@/components/document/index.vue'
import {getAllowDeptList} from '/@/api/sys/dept'
import api from '/@/api/commonApi'

export default {
  name: 'Project',
  components: {
    ProjectDetail,
    Document
  },
  setup() {
    const formRef = ref()
    const groupRef = ref()
    const state = reactive({
      params: {
        current: 1,
        size: 10,
        stageId: null,
        memberIds: null
      },
      stageList: [],
      projectList: [],
      deptList: [],
      enterpriseUsers: [],
      total: 0,
      drawer: false,
      detailData: {},
      formData: {},
      formRules: {
        nickname: {required: true, message: '请输入项目简称', trigger: 'blur'},
        deptId: {required: true, message: '请选择项目归属部门', trigger: 'change'},
        predictEndDate: {required: true, message: '请选择预计结束日期', trigger: 'change'},
        members: {required: true, message: '请选择管理人', trigger: 'change'},
        managerId: {required: true, message: '请选择项目经理', trigger: 'change'},
        stageId: {required: true, message: '请选择项目阶段', trigger: 'change'}
      },
      addVisible: false,
      groupTreeProps: {
        label: 'name',
        children: 'members'
      },
      addGroupVisible: false,
      groupData: {
        name: null,
        sort: 0,
        remark: null,
        members: []
      },
      groupRules: {
        name: {required: true, message: '请填写分组名称', trigger: 'blur'}
      },
      selectedGroup: {
        name: null,
        sort: 0,
        remark: null,
        members: []
      },
      memberIds: [],
      memberTreeProps: {
        key: 'userId',
        label: 'nickname'
      },
      addMemberShow: false,
      filterIds: [],   // 查询的项目成员id列表
      fileList: [],   // 附件/文档列表
    })

    const sizeChange = () => {
      state.params.current = 1
      getProjectData()
    }
    const getProjectData = () => {
      try {
        if (state.filterIds.length > 0) {
          state.params.memberIds = state.filterIds + ''
        } else {
          state.params.memberIds = null
        }
        getProjectPage(state.params).then(res => {
          state.projectList = res.data.records
          state.total = res.data.total
        })
      } catch (e) {
        console.log(e)
      }
    }
    const stageChange = (stageId) => {
      state.params.stageId = stageId === state.params.stageId ? null : stageId
      state.params.current = 1
      getProjectData()
    }
    const openDetail = (project) => {
      state.detailData = project
      state.drawer = true
    }
    const openAdd = () => {
      state.formData = {
        id: null,
        nickname: null,
        name: null,
        managerId: null,
        deptId: null,
        predictEndDate: null,
        stageId: state.stageList.length > 0 ? state.stageList[0].id : null,
        description: null,
        budget: 0,
        relevantList: [],   // 相关方 {"name": "", "contactName": "", "contactPhone": ""}
        groups: [],   // 项目分组 {"name": "", "sort": 0, "members": [{"userId": "", "type": 0}]}
        members: []   // 项目人员（不分配入组） [{"userId": "", "type": 0}]
      }
      state.addVisible = true
    }
    const saveProject = (formRef) => {
      formRef.validate(valid => {
        if (!valid) {
          return false
        }
        let flag = true  // 是否项目经理不在管理人列表中
        state.formData.members.forEach(item => {
          if (item.userId == state.formData.managerId) {
            flag = false
          }
          item.type = 1   // 现在只有项目经理和管理人在人员列表中, 所以默认全部1
        })
        if (flag) {
          state.formData.members.push({
            userId: state.formData.managerId,
            type: 1
          })
        }
        createProject(state.formData).then(res => {
          if (res.data && res.data.id) {
            ElMessage.success('新建成功！')
            if (state.fileList && state.fileList.length > 0) {
              state.fileList.forEach(file => {
                file.relevanceId = res.data.id
                file.relevanceName = res.data.nickname
              })
              api.fileRelevanceModule(state.fileList)
            }
            getProjectData()
            state.addVisible = false
          }
        }).catch(e => console.log(e))
      })
    }
    const removeMember = (node, member) => {
      let parent = node.parent.data  // 人员父级组
      let groups = state.formData.groups
      for (let i = 0; i < groups.length; i++) {
        let group = groups[i]
        if (group.name == parent.name) {
          for (let j = 0; j < group.members.length; j++) {
            if (group.members[j].userId == member.userId) {
              group.members.splice(j, 1)
              break
            }
          }
          break
        }
      }
      state.formData.groups = [...state.formData.groups]
    }
    const toLeader = (member) => {
      member.type = 1
    }
    const removeLeader = (member) => {
      member.type = 0
    }
    const removeGroup = (group) => {
      let groups = state.formData.groups
      for (let i = 0; i < groups.length; i++) {
        let item = groups[i]
        if (item.name == group.name) {
          groups.splice(i, 1)
          break
        }
      }
    }
    const openAddMember = (group) => {
      state.selectedGroup = group
      state.memberIds = []
      if (group.members && group.members.length > 0) {
        group.members.forEach(member => state.memberIds.push(member.userId))
      }
      state.addMemberShow = true
    }
    const addGroup = () => {
      state.groupData = {
        name: null,
        sort: 0,
        remark: null,
        members: []
      }
      state.addGroupVisible = true
    }
    const saveGroup = (groupRef) => {
      groupRef.validate((valid) => {
        if (!valid) {
          return false
        }
        let flag = true
        let groups = state.formData.groups
        if (groups && groups.length > 0) {
          for (let i = 0; i < groups.length; i++) {
            let group = groups[i]
            if (state.groupData.name == group.name) {
              flag = false
              ElMessage.error('已有相同名称分组，请更换另外的名称')
            }
          }
        }
        if (flag) {
          groups.push(state.groupData)
          state.addGroupVisible = false
        }
      })
    }
    const saveMembers = () => {
      let group = state.selectedGroup
      let ids = Object.assign([], state.memberIds)
      if (ids && ids.length > 0) {
        if (group.members && group.members.length > 0) {  // 检查原有人员, 剔除
          for (let i = 0; i < group.members.length; i++) {
            let member = group.members[i]
            let idx = ids.indexOf(member.userId)
            if (idx > -1) {
              ids.splice(idx, 1)
              break
            }
          }
        }
        ids.forEach(memberId => {
          for (let i = 0; i < state.enterpriseUsers.length; i++) {
            let user = state.enterpriseUsers[i]
            if (memberId == user.userId) {
              group.members.push({
                userId: user.userId,
                type: 0,
                name: user.nickname
              })
              break
            }
          }
        })
      } else if (state.selectedGroup.members && state.selectedGroup.members.length > 0) {
        state.selectedGroup.members = []
      }
      // 不会自动检测子节点的数据更新，重新赋值触发重新渲染
      state.formData.groups = [...state.formData.groups]
      state.addMemberShow = false
    }
    const addRelevantItem = () => {
      let relevantList = state.formData.relevantList
      if (relevantList && relevantList.length > 0) {
        let lastItem = relevantList[relevantList.length - 1]
        if (!lastItem.name || !lastItem.contactName || !lastItem.contactPhone) {
          ElMessage.warning('请把项目相关方信息填写完整后再添加新的')
          return false
        }
      }
      state.formData.relevantList.push({
        name: '',
        contactName: '',
        contactPhone: ''
      })
    }
    const minusRelevantItem = (idx) => {
      state.formData.relevantList.splice(idx, 1)
    }
    const search = () => {

    }

    onMounted(() => {
      getProjectData()
      getStageList(1).then(res => state.stageList = res.data).catch(e => console.log(e))
      getEnterpriseUsers().then(res => state.enterpriseUsers = res.data).catch(e => console.log(e))
      getAllowDeptList().then(res => state.deptList = res.data).catch(e => console.log(e))
    })

    return {
      Plus,
      Minus,
      formRef,
      groupRef,
      ...toRefs(state),
      sizeChange,
      getProjectData,
      stageChange,
      openDetail,
      openAdd,
      saveProject,
      removeMember,
      toLeader,
      removeLeader,
      removeGroup,
      openAddMember,
      addGroup,
      saveGroup,
      saveMembers,
      addRelevantItem,
      minusRelevantItem,
      search
    }
  }
}
</script>

<style scoped lang="scss">
.page-container {
  padding: 1px;

  .stateCell {
    position: relative;
    padding: 12px 5px;
    cursor: pointer;
    flex: auto;
    text-align: center;

    .state-num {
      color: var(--el-text-color-regular);
      font-size: 18px;
    }

    .state-name {
      font-weight: normal;
      padding-bottom: 5px;
      font-size: 15px;
      color: var(--el-text-color-primary);
    }

    &:hover {
      .state-num, .state-name {
        color: var(--el-color-primary);
      }
    }
  }

  .state-active {
    .state-num, .state-name {
      color: var(--el-color-primary);
    }

    &::after {
      content: '';
      position: absolute;
      left: 0;
      right: 0;
      bottom: 0;
      width: 50px;
      margin: 0 auto;
      border-bottom: 2px solid var(--el-color-primary);
    }
  }

  .table-box {
    background: #fff;
    margin-top: 5px;

    :deep(.el-table__header-wrapper .el-table__cell) {
      background: var(--el-color-primary-light-9);
      color: var(--next-bg-menuBar-light-1);
    }

    .tableList {
      border: 1px solid var(--el-table-border-color);
      border-bottom: none;

      :deep(thead .cell) {
        display: flex;
        align-items: center;
      }

      :deep(thead .el-icon) {
        margin-top: -2px;
      }

      .primary {
        cursor: pointer;
        color: var(--el-color-primary);
      }
    }
  }

  .form-row {
    margin-bottom: 18px;
  }

  :deep(.el-popper) {
    max-width: 35%;
  }

  :deep(.el-tree-node.is-current > .el-tree-node__content) {
    color: var(--next-bg-topBar);
    font-weight: bold;
    background: var(--el-color-primary);

    .el-button {
      padding: 0 5px;
      color: var(--next-bg-topBar);

      &:hover {
        color: var(--el-color-primary);
      }
    }

    .leader {
      color: var(--el-color-primary) !important;
    }
  }

  .options-btn {
    .el-button {
      visibility: hidden;
    }
  }

  :deep(.el-tree-node) {
    &:hover {
      .options-btn {
        .el-button {
          visibility: visible !important;
        }
      }
    }
  }

  .relevant-icon {
    :deep(.el-icon) {
      margin-right: 0;
    }
  }
}
</style>
